package com.wb.component.filter

import com.wb.component.Slf4j
import com.wb.component.Slf4j.Companion.log
import com.wb.entity.MsgGet
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.Around
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Pointcut
import org.aspectj.lang.reflect.MethodSignature
import org.springframework.stereotype.Component
import java.lang.reflect.Method
import kotlin.jvm.Throws

@Aspect
@Slf4j
@Component
open class FunFilterAspect {


    @Pointcut("@annotation(FunFilters)")
    open fun funFilters() {
    }

    @Pointcut("@annotation(FunFilter)")
    open fun funFilter() {
    }

    @Throws(Exception::class)
    @Around("funFilters()")
    open fun funFiltersBefore(point: ProceedingJoinPoint) {

        var msgGet: MsgGet? = null
        point.args.forEach {
            when (it) {
                is MsgGet -> msgGet = it
            }
        }

        if (msgGet == null) {
            log.warn("过滤器方法监听 => 没有读取到消息")
            return
        }

        val method = (point.signature as MethodSignature).method

        val flag = filter(method, msgGet)

        if (!flag) {
            return
        }

        point.proceed(point.args)

    }


    @Throws(Exception::class)
    @Around("funFilter()")
    open fun funFilterBefore(point: ProceedingJoinPoint) {

        var msgGet: MsgGet? = null
        point.args.forEach {
            when (it) {
                is MsgGet -> msgGet = it
            }
        }

        if (msgGet == null) {
            log.warn("过滤器方法监听 => 没有读取到消息")
            return
        }

        val method = (point.signature as MethodSignature).method

        val flag = filter(method, msgGet)

        if (!flag) {
            return
        }

        point.proceed(point.args)

    }

    companion object {

        fun filter(method: Method, msgGet: MsgGet?): Boolean {
            if (msgGet == null) {
                return false
            }

            if (method.isAnnotationPresent(FunFilters::class.java)) {

                val msg = msgGet.msg

                val funFilters = method.getAnnotation(FunFilters::class.java)

                val flag = funFilters.value.any {
                    when (it.type) {
                        FunFilterType.EQ -> it.key.equals(msg)
                        FunFilterType.START_WITH -> msg.startsWith(it.key)
                        FunFilterType.END_WITH -> msg.endsWith(it.key)
                        FunFilterType.CONTAINS -> msg.contains(it.key)
                        else -> false
                    }
                }
                return flag
            }

            if (method.isAnnotationPresent(FunFilter::class.java)) {

                val msg = msgGet.msg

                val funFilter = method.getAnnotation(FunFilter::class.java)

                val flag = when (funFilter.type) {
                    FunFilterType.EQ -> funFilter.key.equals(msg)
                    FunFilterType.START_WITH -> msg.startsWith(funFilter.key)
                    FunFilterType.END_WITH -> msg.endsWith(funFilter.key)
                    FunFilterType.CONTAINS -> msg.contains(funFilter.key)
                    else -> false
                }

                return flag
            }

            return false
        }

    }

}